/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * File Name          : freertos.c
  * Description        : Code for freertos applications
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2024 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
  */
/* USER CODE END Header */

/* Includes ------------------------------------------------------------------*/
#include "FreeRTOS.h"
#include "task.h"
#include "main.h"
#include "cmsis_os.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "menu.h"
#include "lcd.h"
#include "motor.h"
#include "can_bsp.h"
#include "tim.h"
#include "adc.h"
#include "LCD_Key.h"
#include "usart.h"
#include "retarget.h"
/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */

/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN Variables */
uint8_t BuzzerFlag; //蜂鸣器标志位
uint16_t adc_val[1]; //按键adc值
uint8_t Key, Key_Change; //按键状态
uint8_t Uart1_RxData; //串口接受缓存
uint8_t command; //电机命令
float positon = 0.0; //电机位置
/* USER CODE END Variables */
osThreadId defaultTaskHandle;
osThreadId menuHandle;
osThreadId motor_settingHandle;
osThreadId uart_taskHandle;
osThreadId BuzzerHandle;
osThreadId KeyHandle;

/* Private function prototypes -----------------------------------------------*/
/* USER CODE BEGIN FunctionPrototypes */

/* USER CODE END FunctionPrototypes */

void StartDefaultTask(void const* argument);
void ShowMenu(void const* argument);
void MotorSetting(void const* argument);
void uart_method(void const* argument);
void BuzzerTask(void const* argument);
void LCD_Key(void const* argument);

void MX_FREERTOS_Init(void); /* (MISRA C 2004 rule 8.1) */

/* GetIdleTaskMemory prototype (linked to static allocation support) */
void vApplicationGetIdleTaskMemory(StaticTask_t** ppxIdleTaskTCBBuffer, StackType_t** ppxIdleTaskStackBuffer,
                                   uint32_t* pulIdleTaskStackSize);

/* USER CODE BEGIN GET_IDLE_TASK_MEMORY */
static StaticTask_t xIdleTaskTCBBuffer;
static StackType_t xIdleStack[configMINIMAL_STACK_SIZE];

void vApplicationGetIdleTaskMemory(StaticTask_t** ppxIdleTaskTCBBuffer, StackType_t** ppxIdleTaskStackBuffer,
                                   uint32_t* pulIdleTaskStackSize)
{
    *ppxIdleTaskTCBBuffer = &xIdleTaskTCBBuffer;
    *ppxIdleTaskStackBuffer = &xIdleStack[0];
    *pulIdleTaskStackSize = configMINIMAL_STACK_SIZE;
    /* place for user code */
}

/* USER CODE END GET_IDLE_TASK_MEMORY */

/**
  * @brief  FreeRTOS initialization
  * @param  None
  * @retval None
  */
void MX_FREERTOS_Init(void)
{
    /* USER CODE BEGIN Init */

    /* USER CODE END Init */

    /* USER CODE BEGIN RTOS_MUTEX */
    /* add mutexes, ... */
    /* USER CODE END RTOS_MUTEX */

    /* USER CODE BEGIN RTOS_SEMAPHORES */
    /* add semaphores, ... */
    /* USER CODE END RTOS_SEMAPHORES */

    /* USER CODE BEGIN RTOS_TIMERS */
    /* start timers, add new ones, ... */
    /* USER CODE END RTOS_TIMERS */

    /* USER CODE BEGIN RTOS_QUEUES */
    /* add queues, ... */
    /* USER CODE END RTOS_QUEUES */

    /* Create the thread(s) */
    /* definition and creation of defaultTask */
    osThreadDef(defaultTask, StartDefaultTask, osPriorityNormal, 0, 128);
    defaultTaskHandle = osThreadCreate(osThread(defaultTask), NULL);

    /* definition and creation of menu */
    osThreadDef(menu, ShowMenu, osPriorityIdle, 0, 128);
    menuHandle = osThreadCreate(osThread(menu), NULL);

    /* definition and creation of motor_setting */
    osThreadDef(motor_setting, MotorSetting, osPriorityIdle, 0, 128);
    motor_settingHandle = osThreadCreate(osThread(motor_setting), NULL);

    /* definition and creation of uart_task */
    osThreadDef(uart_task, uart_method, osPriorityIdle, 0, 256);
    uart_taskHandle = osThreadCreate(osThread(uart_task), NULL);

    /* definition and creation of Buzzer */
    osThreadDef(Buzzer, BuzzerTask, osPriorityIdle, 0, 128);
    BuzzerHandle = osThreadCreate(osThread(Buzzer), NULL);

    /* definition and creation of Key */
    osThreadDef(Key, LCD_Key, osPriorityIdle, 0, 128);
    KeyHandle = osThreadCreate(osThread(Key), NULL);

    /* USER CODE BEGIN RTOS_THREADS */
    /* add threads, ... */
    /* USER CODE END RTOS_THREADS */
}

/* USER CODE BEGIN Header_StartDefaultTask */
/**
  * @brief  自定义测试线程
  * @param  argument: Not used
  * @retval None
  */
/* USER CODE END Header_StartDefaultTask */
void StartDefaultTask(void const* argument)
{
    /* USER CODE BEGIN StartDefaultTask */

    /* Infinite loop */
    for (;;)
    {
        osDelay(10);
    }
    /* USER CODE END StartDefaultTask */
}

/* USER CODE BEGIN Header_ShowMenu */
/**
* @brief Function implementing the menu thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_ShowMenu */
void ShowMenu(void const* argument)
{
    /* USER CODE BEGIN ShowMenu */
    LCD_Init(); //LCD初始化
    Menu_show_motor_msg();
    /* Infinite loop */
    for (;;)
    {
        Menu_show_motor_data_refresh();


        osDelay(200);
    }
    /* USER CODE END ShowMenu */
}

/* USER CODE BEGIN Header_MotorSetting */
/**
* @brief 电机发送线程
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_MotorSetting */
void MotorSetting(void const* argument)
{
    /* USER CODE BEGIN MotorSetting */
    static int i = 0;

    void My_Motor_Init(); //初始化电机类型

    //can通信使能
    can_bsp_init();
    //使能可控电源
    HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_SET);
    HAL_GPIO_WritePin(GPIOC, GPIO_PIN_14, GPIO_PIN_SET);
    osDelay(100);


    /* Infinite loop */
    for (;;)
    {
        if (Key_Change == 1)
        {
            switch (Key)
            {
            case MID:
                if (motor[1].enable_state) stop_motor(&motor[1], 0);
                else start_motor(&motor[1]);
                break;
            case LEFT:
                positon += 10.0;
            // printf("%f\r\n", positon);
            case RIGHT:
                positon -= 10.0;
            // printf("%f\r\n", positon);
            case UP:
                positon = 0.0;

            default:
                break;
            }
            Key_Change = 0;
        }

        switch (command)
        {
        case init_position_mode_command: //初始化位置模式
            // 位置模式
            init_motor(&motor[1], 0x01, Position_mode);
            command = null;
            break;
        case position_add_command:
            positon += 1;
            set_position_motor(&motor[1], positon, 2, 1, 8);
            command = null;
            break;
        case position_del_command:
            positon -= 1;
            set_position_motor(&motor[1], positon, 2, 1, 8);
            command = null;
            break;
        case set_zero_command:
            set_zeropos_motor(&motor[1]);
            command = null;
            break;
        case back_zero_command:
            positon = 0;
            set_position_motor(&motor[1], positon, 2, 1, 8);
            command = null;
            break;
        case enable_command:
            start_motor(&motor[1]);
            command = null;
            break;
        case disable_command:
            stop_motor(&motor[1], 0);
            command = null;
            break;
        default:
            break;
        }
        command = 0;

        set_speed_motor(&motor[1], 1);

        osDelay(10);
    }
    /* USER CODE END MotorSetting */
}

/* USER CODE BEGIN Header_uart_method */
//串口接收回调
void HAL_UART_RxCpltCallback(UART_HandleTypeDef* huart)
{
    UNUSED(huart);
    if (huart == &huart1) //判断
    {
        switch (Uart1_RxData)
        {
        case 0xfe: command = init_position_mode_command;
            BuzzerFlag = 1;
            break;
        case 0x0a: command = position_add_command;
            BuzzerFlag = 1;
            break;
        case 0x0b: command = position_del_command;
            BuzzerFlag = 1;
            break;
        case 0x0c: command = set_zero_command;
            BuzzerFlag = 1;
            break;
        case 0x0d: command = back_zero_command;
            BuzzerFlag = 1;
            break;
        case 0xa1: command = enable_command;
            BuzzerFlag = 1;
            break;
        case 0xa2: command = disable_command;
            BuzzerFlag = 1;
            break;
        default:
            break;
        }
        //写协议
        HAL_UART_Receive_IT(&huart1, (uint8_t*)&Uart1_RxData, 1); //再开启接收中断
    }
}

/**
* @brief 串口条件处理线程
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_uart_method */
void uart_method(void const* argument)
{
    /* USER CODE BEGIN uart_method */
    RetargetInit(&huart1);
    printf("--position_test--\r\n");
    HAL_UART_Receive_IT(&huart1, &Uart1_RxData, 1); //先开启接收中断
    /* Infinite loop */
    for (;;)
    {
        printf("position: %.1f", positon);
        osDelay(1000);
    }
    /* USER CODE END uart_method */
}

/* USER CODE BEGIN Header_BuzzerTask */
/**
* @brief 蜂鸣器线程
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_BuzzerTask */
void BuzzerTask(void const* argument)
{
    /* USER CODE BEGIN BuzzerTask */
    HAL_TIM_PWM_Start(&htim12, TIM_CHANNEL_2); //打开定时器的蜂鸣器
    /* Infinite loop */
    for (;;)
    {
        if (BuzzerFlag == 1)
        {
            __HAL_TIM_SET_COMPARE(&htim12, TIM_CHANNEL_2, 50); //修改占空比，使用z值来修改
            osDelay(200);
            __HAL_TIM_SET_COMPARE(&htim12, TIM_CHANNEL_2, 0); //修改占空比，使用z值来修改
            BuzzerFlag = 0;
        }
        osDelay(1);
    }
    /* USER CODE END BuzzerTask */
}

/* USER CODE BEGIN Header_LCD_Key */
/**
* @brief 获取LCD的按键线程
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_LCD_Key */
void LCD_Key(void const* argument)
{
    /* USER CODE BEGIN LCD_Key */
    HAL_ADCEx_Calibration_Start(&hadc1, ADC_CALIB_OFFSET, ADC_SINGLE_ENDED);
    HAL_ADC_Start_DMA(&hadc1, (uint32_t*)adc_val, 1);
    osDelay(1000);
    getInitADC(adc_val[0]);
    /* Infinite loop */
    for (;;)
    {
        Key = ADC_Key(adc_val[0]);

        if (Key != FLOATING)
        {
            Key_Change = 1;
            osDelay(500); //消抖
        }

        osDelay(10);
    }
    /* USER CODE END LCD_Key */
}

/* Private application code --------------------------------------------------*/
/* USER CODE BEGIN Application */

/* USER CODE END Application */
